package mju.cxf.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import mju.cxf.constant.MessageConstant;
import mju.cxf.context.BaseContext;
import mju.cxf.dto.OrderDTO;
import mju.cxf.dto.UserLoginDTO;
import mju.cxf.entity.Integral;
import mju.cxf.entity.Order;
import mju.cxf.entity.User;
import mju.cxf.exception.BindEmailException;
import mju.cxf.exception.CaptchaException;
import mju.cxf.mapper.OrderMapper;
import mju.cxf.service.IntegralService;
import mju.cxf.service.OrderService;
//import org.redisson.api.RedissonClient;
import mju.cxf.service.UserService;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.SimpleFormatter;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private RedissonClient redissonClient;
    /**
     * 用户邮箱绑定模块
     *
     * @param userLoginDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void bind(UserLoginDTO userLoginDto) {
        String email = userLoginDto.getEmail();
        if (email == null || userLoginDto.getCaptcha() == null) {
            throw new BindEmailException(MessageConstant.CAPTCHA_ERROR);
        }
        //获取存储的验证码
        String code = (String) redisTemplate.opsForValue().get("key:"+email);
        if (code == null || !(code.equalsIgnoreCase(userLoginDto.getCaptcha()))) {
            throw new CaptchaException(MessageConstant.CAPTCHA_ERROR);
        }
        redisTemplate.delete("key:"+email);
    }


    @Override
    public Page<OrderDTO> selectPageBynumber(String number, Integer userId, String productName, Integer status, int current, int size) {
        Page<OrderDTO> page = new Page<>(current, size);

        return this.baseMapper.selectPageVo(page, number, userId, productName, status);
    }

    @Override
    public boolean insertOrder(Order order) {
        return orderMapper.insert(order) == 1;
    }

    /**
     * U创建订单
     *
     * @param order
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createOrder(Order order) {
        if (orderMapper.insert(order) > 0) {
            final RBlockingQueue<Object> orderQueue = redissonClient.getBlockingQueue("orderQueue");
            // 尝试将订单添加到队列，最多等待2秒
            final boolean offer;
            try {
                offer = orderQueue.offer(order, 2, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (offer) {
                // 安排过期任务
                scheduler.schedule(() -> {
                    this.changeOrderStatus(order, "过期");
                    orderQueue.remove(order);
                    //五分钟订单过期
                }, 300, TimeUnit.SECONDS);

            } else {
                log.error(order.toString() + "订单队列异常");
            }
            return true;
        }
        return false;
    }

    @Autowired
    private IntegralService integralService;

    /**
     * U订单状态变化
     * @param order 订单信息
     * @param msg 消息
     */
    private void changeOrderStatus(Order order, String msg) {
        final Order orderById = orderMapper.selectById(order.getId());
        if (orderById.getStatus() == 0) {
            this.deleteIntegralNumber(orderById);
        }

    }

    /**
     * U取消后返回扣除积分
     * @param order
     */
    @Transactional
    public void deleteIntegralNumber(Order order) {
        order.setStatus(7);
        final User user = userService.getById(order.getUserId());
        final double integralPrice = order.getIntegralPrice();
        int integral= (int) (integralPrice*1000);
        user.setPoints(user.getPoints()+integral);
        userService.updateById(user);
        if (integralPrice !=0) {
            final Integral build = Integral.builder()
                    .number(integral)
                    .userId(order.getUserId())
                    .createTime(LocalDateTime.now())
                    .type(1)
                    .tittle("订单取消退回")
                    .build();
            integralService.save(build);
        }

        this.updateById(order);
    }

    @Override
    public boolean deleteProduct(Integer id) {
        return this.removeById(id);
    }

    @Override
    public Order selectOrder(Integer id) {
        return this.baseMapper.selectById(id);
    }

    @Override
    public Order sleectOrderNumber(String number) {
        return this.baseMapper.selectOrderNumber(number);
    }
}
